package com.schoolvisitors.response;

import com.schoolvisitors.context.AdminContext;
import com.schoolvisitors.context.UserContext;
import com.schoolvisitors.entity.Admin;
import com.schoolvisitors.entity.LoginToken;
import com.schoolvisitors.entity.User;
import com.schoolvisitors.exception.BusinessException;
import com.schoolvisitors.repository.LoginTokenRepository;
import com.schoolvisitors.service.AdminService;
import com.schoolvisitors.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.util.Arrays;
import java.util.List;

@Slf4j
public class ContextInterceptor implements HandlerInterceptor {
    // 白名单路径列表
    private static final List<String> WHITELIST_PATHS = Arrays.asList(
            "/error", "/api/v1/user/weChatAuth", "/api/v1/user/register", "/api/v1/admin/login", "/api/src/"
    );

    private final LoginTokenRepository loginTokenRepository;
    private final UserService userService;
    private final AdminService adminService;
    public ContextInterceptor(UserService userService, AdminService adminService, LoginTokenRepository loginTokenRepository) {
                this.userService = userService;
        this.loginTokenRepository = loginTokenRepository;
        this.adminService = adminService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();

        log.info("收到请求: {}", requestURI);
        // 如果请求的路径在白名单中，直接放行
        if (isWhitelisted(requestURI)) {
            log.info("白名单: {}", requestURI);
            return true;
        }

        String authorizationHeader = request.getHeader("Authorization");
        if (authorizationHeader == null || authorizationHeader.isEmpty()) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.setContentType("application/json; charset=UTF-8");
            response.getWriter().write("{\"code\":401,\"msg\":\"未授权访问\"}");
            return false;  // 终止请求的进一步处理
        }

        if (requestURI.startsWith("/api/v1/user")) {
            LoginToken loginToken = loginTokenRepository.findTopByRoleAndToken("user", authorizationHeader);
            if (loginToken == null) {
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.setContentType("application/json; charset=UTF-8");
                response.getWriter().write("{\"code\":401,\"msg\":\"未授权访问\"}");
                return false;  // 终止请求的进一步处理
            }
            //log.info("获取到了用户令牌: {} {}", loginToken.getId(), loginToken.getToken());
            User user = userService.findById(loginToken.getIndexId());
            UserContext.setUser(user);
            log.info("用户 {} {} 通过", user.getId(), requestURI);
            return true;
        } else if (requestURI.startsWith("/api/v1/admin")) {
            LoginToken loginToken = loginTokenRepository.findTopByRoleAndToken("admin", authorizationHeader);
            if (loginToken == null) {
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.setContentType("application/json; charset=UTF-8");
                response.getWriter().write("{\"code\":401,\"msg\":\"未授权访问\"}");
                return false;  // 终止请求的进一步处理
            }

            //log.info("获取到了管理员令牌: {} {}", loginToken.getId(), loginToken.getToken());
            Admin admin = adminService.findByAdminId(loginToken.getIndexId()).orElseThrow(() -> new BusinessException(ResultCode.ADMIN_NOT_FOUND));
            AdminContext.set(admin);
            return true;

        }
        log.info("拒绝: {}", requestURI);

        return false;  // 返回 true，表示继续执行请求
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 处理完请求后，可以在这里进行一些操作
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 请求处理完毕后，清理上下文信息
        UserContext.clear();
        AdminContext.clear();
    }

    /**
     * 判断请求路径是否在白名单中
     * @param requestURI 请求路径
     * @return 是否在白名单中
     */
    private boolean isWhitelisted(String requestURI) {
        for (String path : WHITELIST_PATHS) {
//            log.info("wpath: {}   requestURI: {}   requestURI.startsWith(path): {}", path, requestURI, requestURI.startsWith(path));
            if (requestURI.startsWith(path)) {
                return true;
            }
        }
        return false;
    }
}
